/******************************************
 *Author:庄育龙
 *Function:棋盘的绘图事件与对鼠标事件的响应
 *Created Date:2013.05.14
 *Last Modified:2013.05.28
 ******************************************/

#include "chesswidget.h"
#include "win.h"
#include "ai.h"
#include "regret.h"
#include <string>
#include <sstream>
#include <iostream>
#include "data.h"

ChessWidget::ChessWidget(QWidget *parent)
    : QWidget(parent) {

}

void ChessWidget::paintEvent(QPaintEvent *event) {//绘图事件
    QPainter paint(this);
    QPixmap pixmap;
    pixmap.load(QApplication::applicationDirPath()+":/image/wood1.bmp");
    //载入背景
    QPixmap blackmap;
    blackmap.load(QApplication::applicationDirPath()+":/image/black.png");
    //黑棋子
    QPixmap whitemap;
    whitemap.load(QApplication::applicationDirPath()+":/image/white.png");
    //白棋子
    paint.setBrush(Qt::lightGray);
    for(int i=0;i<10;i++) {
        for(int j=0;j<5;j++) {
            paint.drawPixmap(i*50,j*100,pixmap);
            //绘制背景
        }
    }
    for (int x = 40; x <= 460; x += 30)
    {
        paint.drawLine(x, 40, x, 460);
    }
    for (int y = 40; y <= 460; y += 30)
    {
        paint.drawLine(40, y, 460, y);
    }
    //绘出网格线
    QFont font=paint.font();
    font.setPointSize(14);
    font.setBold(1);
    paint.setFont(font);
    for(int i=1;i<10;i++) {
        paint.drawText(15,i*30+15,QString::number(i,10));
    }
    for(int i=10;i<16;i++) {
        paint.drawText(10,i*30+15,QString::number(i,10));
    }
    for(int i=1;i<10;i++) {
        paint.drawText(i*30+5,25,QString::number(i,10));
    }
    for(int i=10;i<16;i++) {
        paint.drawText(i*30,25,QString::number(i,10));
    }
    //绘出表示哪行哪列的数字
    QPainter black(this);
    QPainter white(this);
    for (int x = 0; x < 15; x++) {
        for (int y = 0; y < 15; y++) {
            if (ChessBoard[x][y] == 1) {
                black.drawPixmap(24+x*30,24+y*30,blackmap);
                //ChessBoard里1表示黑子
            }
            else if (ChessBoard[x][y] == 2) {
                white.drawPixmap(24+x*30,24+y*30,whitemap);
                //ChessBoard里2表示白子
            }
        }
    }
    QWidget::paintEvent(event);
}

void ChessWidget::mousePressEvent(QMouseEvent *event) {//响应鼠标事件
    if(IsRun && event->button() == Qt::LeftButton) {//游戏正在运行时才响应鼠标左键事件
        int x=event->x();
        int y=event->y();
        if(x<25||y<25||x>475||y>475) {
            return;
        }
        //如果鼠标按的地方在有效位置以外就跳出
        for(int i=0;i<15;i++) {
            if(x>=25+i*30 && x<=55+i*30) {
                x=i;
                break;
            }
        }
        for(int i=0;i<15;i++) {
            if(y>=25+i*30 && y<=55+i*30) {
                y=i;
                break;
            }
        }
        //把绝对坐标转化为棋盘上的坐标

        if(ChessBoard[x][y]==0) {//如果这一点没有子才进行以下操作
            if(lan) {//如果是局域网游戏的话要发送newpoint信号，并且下完后立刻令IsRun=false，防止连下两子
                if(IsHumanFirst) {
                    ChessBoard[x][y]=1;
                    newpoint(x,y);
                    additem(x,y,1);//添加棋子到listwidget
                    push(x,y,1);//添加棋子到栈中
                    if(DoForbidden && isban(x,y)) {//如果开启了禁手而且下到禁手点的话游戏结束
                        additem(15,15,2);//添加赢的信息到listwidget
                        win(2,true);//发送游戏结束的信号，true表示触发了禁手
                        return;
                    }
                    else if(IsWin(x,y,1)==1) {//如果黑方取胜
                        additem(15,15,1);//添加赢的信息到listwidget
                        win(1,false);//发送游戏结束的信号
                        return;
                    }
                    else if(IsWin(x,y,1)==2) {//如果双方战平
                        additem(16,16,1);//添加平的信息到listwidget
                        win(4,false);//发送游戏结束的信号
                        return;
                    }
                }
                else {//同上
                    ChessBoard[x][y]=2;
                    newpoint(x,y);
                    additem(x,y,1);
                    push(x,y,2);
                    if(IsWin(x,y,2)==1) {
                        additem(15,15,1);
                        win(1,false);
                        return;
                    }
                    else if(IsWin(x,y,2)==2) {
                        additem(16,16,1);
                        win(4,false);
                        return;
                    }
                }
                send(false);
                IsRun=false;
                update();
                return;//不进行下面的操作直接跳出
            }
            if(IsComputer && IsHumanFirst) {//人机对战且人先手，说明人执黑
                //具体进行的各项操作基本同上
                ChessBoard[x][y]=1;
                additem(x,y,1);
                push(x,y,1);
                if(DoForbidden && isban(x,y)) {
                    additem(15,15,2);
                    win(2,true);
                    return;

                }
                else if(IsWin(x,y,1)==1) {
                    additem(15,15,1);
                    win(1,false);
                    return;
                }
                else if(IsWin(x,y,1)==2) {
                    additem(16,16,1);
                    win(4,false);
                    return;
                }
                else if(Difficulty==3) {//如果选择了困难AI
                    QString x1=QString::number(x);
                    QString y1=QString::number(y);
                    QString write="[PUT] "+x1+" "+y1+"\n";
                    const char *p = write.toStdString().data();
                    cmd1.write(p);
                    IsRun=false;
                }
            }
            else if(IsComputer && !IsHumanFirst) {//同上
                ChessBoard[x][y]=2;
                additem(x,y,1);
                push(x,y,2);
                if(IsWin(x,y,2)==1) {
                    additem(15,15,1);
                    win(1,false);
                    return;
                }
                else if(IsWin(x,y,2)==2) {
                    additem(16,16,1);
                    win(4,false);
                    return;
                }
                else if(Difficulty==3) {
                    QString x1=QString::number(x);
                    QString y1=QString::number(y);
                    QString write="[PUT] "+x1+" "+y1+"\n";
                    const char *p = write.toStdString().data();
                    cmd1.write(p);
                    IsRun=false;
                }
            }
            else if(!IsComputer && HumanBlack) {//人人对战，黑棋，同上
                ChessBoard[x][y]=1;
                HumanBlack=false;
                additem(x,y,1);
                push(x,y,1);
                if(DoForbidden && isban(x,y)) {
                    additem(15,15,2);
                    win(2,true);
                    return;
                }
                else if(IsWin(x,y,1)==1) {
                    additem(15,15,1);
                    win(1,false);
                    return;
                }
                else if(IsWin(x,y,1)==2) {
                    additem(16,16,1);
                    win(4,false);
                    return;
                }
                //先判断获胜
                send(HumanBlack);
            }
            else {//人人对战，白棋，同上
                ChessBoard[x][y]=2;
                additem(x,y,2);
                push(x,y,2);
                HumanBlack=true;
                if(IsWin(x,y,2)==1) {
                    additem(15,15,2);
                    win(2,false);
                    return;
                }
                else if(IsWin(x,y,2)==2) {
                    additem(16,16,1);
                    win(4,false);
                    return;
                }
                send(HumanBlack);
            }
            if(IsComputer) {//电脑下子
                int *p=new int;
                int *q=new int;

                send(false);
                if(Difficulty==1) {//简单电脑调用AI函数
                    AI(p,q);
                }
                else if(Difficulty==2) {//中等调用AI1函数
                    AI1(p,q);
                }
                //以上函数通过指针返回值
                else {//困难的时候直接返回
                    return;
                }
                if(IsHumanFirst) {//同上
                    ChessBoard[*q][*p]=2;
                    additem(*q,*p,3);
                    push(*q,*p,2);
                    if(IsWin(*q,*p,2)==1) {
                        additem(15,15,3);
                        win(3,false);
                        return;
                    }
                    else if(IsWin(*q,*p,2)==2) {
                        additem(16,16,1);
                        win(4,false);
                        return;
                    }
                }
                else {
                    ChessBoard[*q][*p]=1;
                    additem(*q,*p,3);
                    push(*q,*p,1);
                    if(IsWin(*q,*p,1)==1) {
                        additem(15,15,3);
                        win(3,false);
                        return;
                    }
                    else if(IsWin(*q,*p,1)==2) {
                        additem(16,16,1);
                        win(4,false);
                        return;
                    }
                }//行动结束
                send(true);
            }
        }

    }
    update();//刷新ChessWidget
}

void ClearBoard() {//清空棋盘
    for(int i=0;i<15;i++) {
        for(int j=0;j<15;j++) {
            ChessBoard[i][j]=0;
        }
    }
}

void ChessWidget::Connect() {//从connect.exe读取数据
    QString temp=cmd1.readLine();//读取一行
    const char *p = temp.toStdString().data();//转为字符指针
    istringstream temp1(p);//转为字符串流
    int x;
    int y;
    temp1 >> x >> y;
    //从temp1流中读取数字
    if(IsHumanFirst) {//此处同上方257行
        ChessBoard[x][y]=2;
        additem(x,y,3);
        push(x,y,2);
        if(IsWin(x,y,2)==1) {
            additem(15,15,3);
            win(3,false);
            return;
        }
    }
    else {
        ChessBoard[x][y]=1;
        additem(x,y,3);
        push(x,y,1);
        if(IsWin(x,y,1)==1) {
            additem(15,15,3);
            win(3,false);
            return;
        }
    }
    IsRun=true;//允许下子
    send(true);
    update();
}
